
#ifndef XL9535_H
#define XL9535_H


#define XL9535_I2C_ADDR 0x21  // A2=0 A1=0 A0=1

// Define the register addresses
#define XL9535_INPUT_PORT_0_REGISTER 0x00
#define XL9535_INPUT_PORT_1_REGISTER 0x01
#define XL9535_OUTPUT_PORT_0_REGISTER 0x02
#define XL9535_OUTPUT_PORT_1_REGISTER 0x03
#define XL9535_INVERSION_PORT_0_REGISTER 0x04
#define XL9535_INVERSION_PORT_1_REGISTER 0x05
#define XL9535_CONFIG_PORT_0_REGISTER 0x06
#define XL9535_CONFIG_PORT_1_REGISTER 0x07

#define XL9535_GPIO_FLAG_INPUT 1
#define XL9535_GPIO_FLAG_OUTPUT 0

typedef struct {
    uint8_t dev_addr;
    uint32_t clk_speed;
    // uint8_t addr_wordlen;               /*!< block address wordlen */
    // uint8_t write_time_ms;              /*!< xl9535 write time, typically 10ms*/
} i2c_xl9535_config_t;

typedef struct i2c_xl9535 {
    void *i2c_dev;      /*!< I2C device handle */
    uint8_t addr_wordlen;                 /*!< block address wordlen */
    uint8_t *buffer;                      /*!< I2C transaction buffer */
    uint8_t write_time_ms;                /*!< I2C xl9535 write time(ms)*/
} i2c_xl9535_t;

/* handle of xl9535 device */
typedef struct i2c_xl9535 *i2c_xl9535_handle_t;

#define XL9535_USE_DEFAULT_HANDLE
#ifdef XL9535_USE_DEFAULT_HANDLE
#define XL9535_MAX_I2C_DEVICE 2
extern i2c_xl9535_handle_t i2c_dev_xl9535[XL9535_MAX_I2C_DEVICE];
#endif

esp_err_t xl9535_init(void *bus_handle, const i2c_xl9535_config_t *xl9535_config, i2c_xl9535_handle_t *xl9535_handle);

// Declare the functions that correspond to the C++ class methods
int xl9535_digital_read(i2c_xl9535_handle_t dev_handle, uint8_t pin);
void xl9535_digital_write(i2c_xl9535_handle_t dev_handle, uint8_t pin, bool value);
void xl9535_pin_mode(i2c_xl9535_handle_t dev_handle, uint8_t pin, uint8_t mode);

// Additional struct to represent a GPIO pin in the XL9535 context
typedef struct {
    i2c_xl9535_handle_t parent;
    uint8_t pin;
    bool inverted;
    uint8_t flags;
} xl9535_gpio_t;

// Function declarations for GPIO pin operations
void xl9535_gpio_pin_setup(xl9535_gpio_t *gpio_pin);
char* xl9535_gpio_pin_dump_summary(xl9535_gpio_t *gpio_pin);
void xl9535_gpio_pin_mode(xl9535_gpio_t *gpio_pin, uint8_t flags);
int xl9535_gpio_digital_read(xl9535_gpio_t *gpio_pin);
void xl9535_gpio_digital_write(xl9535_gpio_t *gpio_pin, bool value);

#endif // XL9535_H
